import hljsLangs from '../core/hljs/lang.hljs.js'
import {
    loadScript
} from '../core/extra-function.js'

function getMarkdown(option = {}) {
    var markdown_config = {
        html: true,        // Enable HTML tags in source
        xhtmlOut: true,        // Use '/' to close single tags (<br />).
        breaks: true,        // Convert '\n' in paragraphs into <br>
        langPrefix: 'lang-',  // CSS language prefix for fenced blocks. Can be
        linkify: false,        // 自动识别url
        typographer: true,
        quotes: '“”‘’',
        ...option
    }

    var markdown = require('markdown-it')(markdown_config);
    // 表情
    var emoji = require('markdown-it-emoji');
    // 下标
    var sub = require('markdown-it-sub')
    // 上标
    var sup = require('markdown-it-sup')
    // <dl/>
    var deflist = require('markdown-it-deflist')
    // <abbr/>
    var abbr = require('markdown-it-abbr')
    // footnote
    var footnote = require('markdown-it-footnote')
    // insert 带有下划线 样式 ++ ++
    var insert = require('markdown-it-ins')
    // mark
    var mark = require('markdown-it-mark')
    // taskLists
    var taskLists = require('markdown-it-task-lists')
    // container
    var container = require('markdown-it-container')
    //
    var toc = require('markdown-it-toc')
    // add target="_blank" to all link
    var defaultRender = markdown.renderer.rules.link_open || function (tokens, idx, options, env, self) {
        return self.renderToken(tokens, idx, options);
    };
    markdown.renderer.rules.link_open = function (tokens, idx, options, env, self) {
        var hIndex = tokens[idx].attrIndex('href');
        if (tokens[idx].attrs[hIndex][1].startsWith('#')) return defaultRender(tokens, idx, options, env, self);
        // If you are sure other plugins can't add `target` - drop check below
        var aIndex = tokens[idx].attrIndex('target');

        if (aIndex < 0) {
            tokens[idx].attrPush(['target', '_blank']); // add new attribute
        } else {
            tokens[idx].attrs[aIndex][1] = '_blank';    // replace value of existing attr
        }

        // pass token to default renderer.
        return defaultRender(tokens, idx, options, env, self);
    };
    var mihe = require('markdown-it-highlightjs-external');
    // math katex
    var katex = require('markdown-it-katex-external');
    var miip = require('markdown-it-images-preview');
    var missLangs = {};
    var needLangs = [];
    var hljs_opts = {
        hljs: 'auto',
        highlighted: true,
        langCheck: function (lang) {
            if (lang && hljsLangs[lang] && !missLangs[lang]) {
                missLangs[lang] = 1;
                needLangs.push(hljsLangs[lang])
            }
        }
    };
    markdown.use(mihe, hljs_opts)
        .use(emoji)
        .use(sup)
        .use(sub)
        .use(container)
        .use(container, 'hljs-left') /* align left */
        .use(container, 'hljs-center')/* align center */
        .use(container, 'hljs-right')/* align right */
        .use(deflist)
        .use(abbr)
        .use(footnote)
        .use(insert)
        .use(mark)
        .use(container)
        .use(miip)
        .use(katex)
        .use(taskLists)
        .use(toc);
    return {markdown, hljs_opts, needLangs, missLangs};
}

const {markdown, hljs_opts, missLangs, needLangs} = getMarkdown(
    this.markedItOptions
);

export default {
    props: {
        markedItOptions: Object
    },
    data() {
        return {
            markdownIt: markdown,
            hljs_opts: hljs_opts,
            needLangs: needLangs,
            missLangs: missLangs
        }
    },
    created() {
        const {markdown, hljs_opts, missLangs, needLangs} = getMarkdown(
            this.markedItOptions
        );
        this.markdownIt = markdown;
        this.hljs_opts = hljs_opts;
        this.missLangs = missLangs;
        this.needLangs = needLangs;
    },
    mounted() {
        var $vm = this;
        this.hljs_opts.highlighted = this.ishljs;
    },
    methods: {
        $render(src, func) {
            var $vm = this;
            this.missLangs = {};
            this.needLangs = [];
            var res = this.markdownIt.render(src);
            if (this.ishljs) {
                if (this.needLangs.length > 0) {
                    $vm.$_render(src, func, res);
                }
            }
            func(res);
        },
        $_render(src, func, res) {
            var $vm = this;
            var deal = 0;
            for (var i = 0; i < this.needLangs.length; i++) {
                var url = $vm.p_external_link.hljs_lang(this.needLangs[i]);
                loadScript(url, function () {
                    deal = deal + 1;
                    if (deal === this.needLangs.length) {
                        res = this.markdownIt.render(src);
                        func(res);
                    }
                })
            }
        }
    },
    watch: {
        ishljs: function (val) {
            this.hljs_opts.highlighted = val;
        }
    }
};
